/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servergui;

import Account.AccountManager;
import Shared.PackageTransfer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import javax.net.ssl.SSLSocket;

/**
 *
 * @author Backkom
 */
public class TransferClientRun implements Runnable {

    public boolean canRun = false;
    SSLSocket myClient;
    ServerScreen sv;
    public ObjectInputStream ois;
    public ObjectOutputStream oos;
    AccountManager accountCheck;

    TransferClientRun(SSLSocket Client, ServerScreen server) {
        myClient = Client;
        sv = server;
        try {
            ois = new ObjectInputStream(myClient.getInputStream());
            oos = new ObjectOutputStream(myClient.getOutputStream());
            canRun = true;
        } catch (IOException ex) {
            canRun = false;
        }
        accountCheck = new AccountManager();
    }

    @Override
    public void run() {
        if (canRun) {
            try {
                //Listen account verify
                PackageTransfer jav = (PackageTransfer) ois.readObject();
                if (jav.header.equals("jav")) {
                    String[] str = (String[]) jav.datas;
                    PackageTransfer dbName = new PackageTransfer("sc");
                    if (accountCheck.CreateList(sv.getTable("AccountManager", "Accounts"), str[0], str[1])) {
                        dbName.datas = sv.serverinfo;
                        sendRespone(dbName, oos);
                    } else {
                        dbName.header = "fail";
                        sendRespone(dbName, oos);
                    }
                    do {
                        //Do something for transfer                            
                        PackageTransfer request = (PackageTransfer) ois.readObject();
                        PackageTransfer sc = new PackageTransfer("success");
                        Vector datas = sv.Process(request, sc);
                        if (sc.header.equals("maintain")) {
                            sendRespone(PackageCreate.getMaintainPK("Server is maintaining"),
                                    oos);
                        } else if (sc.header.equals("success")) {
                            if (datas != null) {
                                PackageTransfer[] pk = Transfer2PK(datas);
                                for (int i = 0; i < pk.length; i++) {
                                    sendRespone(pk[i], oos);
                                }
                            } else //Insert,update,delete success
                            {
                                sc.datas = "Query database successfully";
                                sendRespone(sc, oos);
                            }
                        } else {
                            String data = "Query have error\nNOTE: Query you send must be"
                                    + " insert,update,delete or select query";
                            sc.datas = data;
                            sendRespone(sc, oos);
                        }

                    } while (!myClient.isClosed());
                    sv.Output.append("Client at port " + Integer.toString(myClient.getPort())
                            + " close connect!\n");
                } else {
                    sv.Output.append("Client at port " + Integer.toString(myClient.getPort())
                            + " is anonymous!\n");
                }
            } catch (IOException | ClassNotFoundException ex1) {
                System.out.println(ex1.toString());
                try {
                    if (!myClient.isClosed()) {
                        sv.Output.append("Client at port " + Integer.toString(myClient.getPort())
                                + " interrupt connect unexpectly!\n");
                    } else {
                        if (sv.active) {
                            sv.Output.append("Error transfer with client at " + myClient.getLocalAddress().toString()
                                    + " at port " + Integer.toString(myClient.getPort()) + ".\n");
                            sendRespone(PackageCreate.getAbortPK(ex1.toString()),
                                    oos);
                        }
                    }
                } catch (IOException ex) {
                    sv.Output.append("Client at " + myClient.getLocalAddress().toString()
                            + " interrupt connect unexpectly!\n");
                }
            }
        }
    }

    private synchronized void sendRespone(PackageTransfer pk, ObjectOutputStream oos) throws IOException {
        oos.writeObject(pk);
        oos.flush();
    }

    private PackageTransfer[] Transfer2PK(Vector data) {
        if (data != null) {
            PackageTransfer[] pk;
            if (data.isEmpty()) {
                pk = new PackageTransfer[1];
                pk[0] = new PackageTransfer("nonresult");
            } else {
                pk = new PackageTransfer[data.size() + 2];
                pk[0] = new PackageTransfer("Result");
                pk[0].datas = data.firstElement();
                pk[data.size() + 1] = new PackageTransfer("Finish");
                for (int i = 1; i < pk.length - 1; i++) {
                    pk[i] = new PackageTransfer("row");
                    pk[i].datas = data.elementAt(i - 1);
                }
            }
            return pk;
        }
        return null;
    }
}
